<?php

namespace common\cachedb\service;

use think\Config;
use phpFastCache\CacheManager;
use phpFastCache\Helper\Psr16Adapter;

/**
 * 缓存中数组的处理,引用了第三方的缓存类,全部按数组方式处理,不考虑对象方式.
 * 
 * @author chenliming <19536238@qq.com>
 * @since     2018-04-24
 *
 * get($key, $default = null);
 * set($key, $value, $ttl = null);
 * delete($key);
 * clear();
 * getMultiple($keys, $default = null);
 * setMultiple($values, $ttl = null);
 * deleteMultiple($keys);
 * has($key)
 */
class CacheDB {

    protected $cache, $key, $InstanceCache;
    protected $const, $ishit;

    // $type=1 用户缓存
    // $type = 2 普通缓存
    public function __construct($key = '', $type = 1) {
        //key如果获取不到,则取Tag.注意,这个是别名,不是key

        $config = array();
        $config['host'] = empty(Config::get('redis_host')) ? '127.0.0.1' : Config::get('redis_host');
        $config['port'] = empty(Config::get('redis_port')) ? '6379' : Config::get('redis_port');

        $this->key = '';

        if (!empty($key)) {
            $this->InstanceCache = CacheManager::getInstance('redis', $config);
            //判断是什么类型的缓存/用户态
            switch ($type) {
                case 1:
                    //先找tag内容
                    $this->cache = $this->InstanceCache->getItemsByTag($key);
                    //为空说明别名不存在
                    if (empty($this->cache)) {
                        //用户基本数据缓存,注意,用户数据应该是个集合,不是简单的key
                        $this->key = 'user_' . $key;
                        $this->cache = $this->InstanceCache->getItem($this->key);
                    } else {
                        //用取键名的方式取出对象.
                        $this->cache = $this->cache[array_keys($this->cache)[0]];
                    }
                    $this->ishit = $this->cache->isHit();
                    break;
                case 2:
                    //先找tag内容
                    $this->cache = $this->InstanceCache->getItemsByTag($key);
                    //为空说明别名不存在
                    if (empty($this->cache)) {
                        //用户基本数据缓存,注意,用户数据应该是个集合,不是简单的key
                        $this->key = $key;
                        $this->cache = $this->InstanceCache->getItem($this->key);
                    } else {
                        //用取键名的方式取出对象.
                        $this->cache = $this->cache[array_keys($this->cache)[0]];
                    }
                    $this->ishit = $this->cache->isHit();
                    break;
                case 3:
                    //用户基本数据缓存,注意,用户数据应该是个集合,不是简单的key
                    $this->key = 'user_statistics_' . $key;
                    $this->cache = $this->InstanceCache->getItem($this->key);

                    $this->ishit = $this->cache->isHit();
                    break;
                default:
                    break;
            }
        } else {
//            $defaultDriver = (!empty($argv[1]) ? ucfirst($argv[1]) : 'Files');
            $this->cache = new Psr16Adapter('Files');
            $this->cache = new Psr16Adapter('Redis', $config);
        }
    }

    /**
     * 获取字段值
     * @access public
     * @param string $condition 字段名,为空时取全部值
     * @return mixed
     * @since   2016-09-16
     * @author chenliming <chenliming@lacertafashion.com>
     */
    public function get($condition = '') {
        if (empty($this->key)) {
            $this->cache->get($condition);
        } else {
            $data = $this->cache->get();
            if (is_null($data)) {
                return FALSE;
            }
            //判断不同类型不同处理方式
            if (is_array($data)) {
                if (empty($condition)) {
                    return $data;
                } else {
                    //分割输出,如果有不存在的值,返回会假
                    $no_cache = TRUE;
                    $list = [];
                    $map = explode(',', $condition);
                    foreach ($map as $key) {
                        if (isset($data[$key])) {
                            $list[$key] = $data[$key];
                        } else {
                            $no_cache = FALSE;
                            break;
                        }
                    }
                    if ($no_cache == FALSE) {
                        return FALSE;
                    }

                    return $list;
                }
            } else {
                return $data;
            }
        }
    }

    /**
     * 保存内容
     * @access public
     * @param mixed $data 内容,可以为数组可以为字符串
     * @param int $long 保存时长
     * @return mixed
     * @since   2016-09-16
     * @author chenliming <chenliming@lacertafashion.com>
     */
    public function set($tagName = '', $data = '', $ttl = 0) {
        if (empty($this->key)) {
            $this->cache->set($tagName, $data);
        } else {
            //先判断是否存在,存在则是更新
            //默认0为5个月
            $tmp = $this->cache->get();
            if (empty($tmp)) {
                if (empty($tagName)) {
                    $this->cache->set($data)->expiresAfter($ttl);
                } else {
                    $this->cache->set($data)->expiresAfter($ttl)->addTag($tagName);
                }
            } else {
                // 更新数据
                if (is_array($data)) {
                    // 先把数组更新
                    foreach ($data as $key => $value) {
                        $tmp[$key] = $value;
                    }
                    if (empty($tagName)) {
                        $this->cache->set($tmp)->expiresAfter($ttl);
                    } else {
                        $this->cache->set($tmp)->expiresAfter($ttl)->addTag($tagName);
                    }
                } else {
                    if (empty($tagName)) {
                        $this->cache->set($data)->expiresAfter($ttl);
                    } else {
                        $this->cache->set($data)->expiresAfter($ttl)->addTag($tagName);
                    }
                }
            }
            return $this->InstanceCache->save($this->cache);
        }
    }

    /**
     * 判断缓存是否存在
     * @access public
     * @param  string $name 缓存变量名
     * @return bool
     */
    public function has($name) {
        return $this->InstanceCache->has($name);
    }

    /**
     * 清除全部缓存
     * @access public
     * @return boolean
     */
    public function clear() {
        return $this->InstanceCache->clear();
    }

    /**
     * 删除缓存
     * @access public
     * @param  string $name 缓存标识
     * @return boolean
     */
    public function rm($name = '') {
        if (empty($this->key)) {
            return $this->cache->delete($name);
        } else {
            return $this->InstanceCache->deleteItem($this->key);
        }
    }

}
